home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / comm / comm2 / ctsrc701.lha / netcache.c < prev    next >
C/C++ Source or Header  |  1996-12-28  |  18KB  |  713 lines

  1. /*
  2. *       netcache.c
  3. *
  4. * Networking functions for handling network cache (fast transfers).
  5. */
  6. /*
  7. *       history
  8. *
  9. * 91Sep20 HAW Created.
  10. */
  11. #include "ctdl.h"
  12. #define MAP_FILE  "map.$$$"
  13. #define FAST_TEMPLATE "fast$$$.%s"
  14. #define FAST_RECEIVE  "fast_tr.%s"
  15. #define NETMSGS   "netmsgs.%s"
  16. /*
  17. *       contents
  18. *
  19. */
  20. char RecMassTransfer;
  21. char MassTransferSent;
  22. char Zmodem = 0;
  23. static int MTCompVal;
  24.  
  25.  
  26. extern char logNetResults;
  27. extern char netDebug;
  28.  
  29.  
  30. extern CONFIG    cfg;   /* Lots an lots of variables    */
  31. extern char      *SR_Sent;
  32. extern MessageBuffer   msgBuf;
  33. extern char      inReceive;
  34. extern NetBuffer netTemp;
  35. extern char      inNet;
  36. extern NetBuffer netBuf;
  37. extern FILE  *netLog;
  38. extern rTable    *roomTab;
  39. extern FILE  *upfd;
  40. extern int   callSlot;
  41. extern NetTable  *netTab;
  42. extern int       thisNet;
  43. extern char  *READ_ANY, *APPEND_ANY;
  44. /*
  45. * FileMap
  46. *
  47. * This structure is used to map between a filename and the room it's
  48. * carrying.
  49. */
  50. typedef struct
  51.   {
  52.   char *FileName;
  53.   char *RoomName;
  54.  
  55.   }
  56. FileMap;
  57. /*
  58. * Mappings
  59. *
  60. * This is a list of mappings for our current work.
  61. */
  62. static void FreeMapping();
  63. SListBase Mappings =
  64.   {
  65.   NULL, NULL, NULL, FreeMapping, NULL
  66.  
  67.   };
  68. /*
  69. * SendFastTransfer()
  70. *
  71. * We want to use Facility 21, the mass transfer of messages.
  72. */
  73. char SendFastTransfer()
  74.   {
  75.   long   size;
  76.   extern long netBytes;
  77.   extern AN_UNSIGNED RecBuf[SECTSIZE + 5];
  78.   struct cmd_data cmds;
  79.   char BaseArcName[15], Outgoing;
  80.   int protocol;
  81.   char ArcFileName[100];
  82.   char CacheDir[70];
  83.   int RoomOutgoing(SharedRoom *room, int system, int index, int roomslot,  char *d);
  84.   int UnCacheRoom(SharedRoom *room, int system, int index, int roomslot,  void *d);
  85.  
  86.   if ( logNetResults && netDebug )splitF(netLog, "SendFastTransfer:%sabled\n", netBuf.nbflags.MassTransfer ? " En" : "Dis");
  87.   if (!netBuf.nbflags.MassTransfer)    return FALSE;
  88.   if (!netBuf.nbflags.local &&
  89.   !(netBuf.nbflags.spine || inReceive))
  90.     {
  91.     if( logNetResults )
  92.       {
  93.       if( netDebug )
  94.         {
  95.         if( !netBuf.nbflags.local )splitF(netLog, "SendFastTransfer:FALSE, Not Local\n");
  96.         if(  netBuf.nbflags.spine )splitF(netLog, "SendFastTransfer:FALSE, A Spine\n");
  97.         if(             inReceive )splitF(netLog, "SendFastTransfer:FALSE, We have been called\n");
  98.         };
  99.       splitF(netLog, "Mass Transfer flag ignored\n");
  100.       };
  101.     return FALSE;
  102.  
  103.     }
  104.   if (!CompAvailable(GetCompression(thisNet)))
  105.     {
  106.     if (netDebug)splitF(netLog, "SendFastTransfer:FALSE, No compression set\n");
  107.     return FALSE;
  108.  
  109.     }
  110.   /* do we have rooms to send??? */
  111.   Outgoing = FALSE;
  112.   EachSharedRoom(thisNet, RoomOutgoing, VirtualRoomOutgoing, &Outgoing);
  113.   if (!Outgoing)
  114.     {
  115.     MassTransferSent = TRUE;
  116.     EachSharedRoom(thisNet, UnCacheRoom, UnCacheVirtualRoom, NULL);
  117.     if ( logNetResults && netDebug )splitF(netLog, "SendFastTransfer:FALSE, No rooms to send\n");
  118.     return FALSE;
  119.  
  120.     }
  121.   zero_struct(cmds);
  122.   sPrintf(cmds.fields[0], "%d", GetCompression(thisNet));
  123.   sPrintf(cmds.fields[1], "%d", ZM_PROTOCOL);
  124.   strCpy(cmds.fields[2], "0");
  125.   strCpy(cmds.fields[3], "-1");
  126.   cmds.command = FAST_MSGS;
  127.   protocol = ZM_PROTOCOL;
  128.   if (!Zmodem || FindProtocolCode(Zmodem, FALSE) == -1 ||
  129.   !sendNetCommand(&cmds, "mt"))
  130.     {
  131.     sPrintf(cmds.fields[1], "%d", DEFAULT_PROTOCOL);
  132.     protocol = DEFAULT_PROTOCOL;
  133.     if (!sendNetCommand(&cmds, "mt"))
  134.       {
  135.       if( logNetResults && netDebug )splitF(netLog, "Fast Transfer refused\n");
  136.       return FALSE;
  137.  
  138.       }
  139.  
  140.     }
  141.   if (SendMapFile())
  142.     {
  143.     if (!MapFileAccepted())
  144.       {
  145.       if ( logNetResults && netDebug )splitF(netLog, "SendFastTransfer:FALSE, MAP File problem\n");
  146.       return FALSE;
  147.  
  148.       }
  149.     CacheSystem(thisNet, FALSE);
  150.     outMod(ACK);
  151.     sPrintf(BaseArcName, NETMSGS, CompExtension(GetCompression(thisNet)));
  152.     NetCacheName(ArcFileName, thisNet, BaseArcName);
  153.     if( logNetResults && netDebug )splitF(netLog, "Mass Transfer: %s\n",ArcFileName);
  154.     if (protocol == DEFAULT_PROTOCOL)
  155.       SendHostFile(ArcFileName);
  156.     else
  157.       {
  158.       ExternalTransfer(FindProtocolCode(Zmodem, FALSE), ArcFileName);
  159.       while (MIReady()) inp();
  160.       pause(80);   /* keep the other system from eating our NAK */
  161.  
  162.       }
  163.     if (gotCarrier())
  164.       {
  165.       ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  166.       if (RecBuf[0] == BAD || !gotCarrier())
  167.         {
  168.         if ( logNetResults && netDebug )splitF(netLog, "SendFastTransfer:FALSE, lost carrier, or bad transmission\n");
  169.         return FALSE;
  170.         };
  171.       MassTransferSent = TRUE;
  172.       EachSharedRoom(thisNet, UnCacheRoom, UnCacheVirtualRoom, NULL);
  173.       MakeNetCacheName(CacheDir, thisNet);
  174.       if (logNetResults && netDebug)splitF(netLog, "CacheDir:%s\n",CacheDir);
  175.       if (ChangeToCacheDir(CacheDir) == 0)
  176.         {
  177.         netBytes = 0l;
  178.         wildCard(getSize, BaseArcName, FALSE, "", FALSE);
  179.         size = netBytes;
  180.         netBytes = 0l;
  181.         wildCard(getSize, CACHED_FILES, FALSE, "", FALSE);
  182.         wildCard(DelFile, ALL_FILES, FALSE, "", FALSE);
  183.         if( logNetResults && netDebug )splitF(netLog, "MT: %ld => %ld\n", netBytes, size);
  184.  
  185.         }
  186.       homeSpace();
  187.       return TRUE;
  188.  
  189.       }
  190.  
  191.     }
  192.   if ( logNetResults && netDebug )splitF(netLog, "SendFastTransfer:FALSE, problem with sendmapfile()\n");
  193.   return FALSE;
  194.  
  195.   }
  196. /*
  197. * RoomOutgoing()
  198. *
  199. * This is responsible for deciding if the given shared room has outgoing
  200. * material in a room eligible for mass transfers.
  201. */
  202. int RoomOutgoing(SharedRoom *room, int system, int index, int roomslot,
  203. char *d)
  204.   {
  205.   if (strLen(roomTab[roomslot].rtname) && HasOutgoing(system, index))
  206.     {
  207.     *d = TRUE;
  208.     return ERROR;
  209.  
  210.     }
  211.   return TRUE;
  212.  
  213.   }
  214. /*
  215. * SendMapFile()
  216. *
  217. * This sends a file containing the names of rooms to share and the filenames
  218. * in the upcoming archive file to map the rooms to.  Format is a series of
  219. * pairs of lines (UNIX style), first the roomname and then the filename.
  220. * blank line signals end of file.
  221. */
  222. char SendMapFile()
  223.   {
  224.   int NormalRoomMap(SharedRoom *room, int system, int index, int roomslot,
  225.   void *d);
  226.   if (!ITL_Send(STARTUP)) return FALSE;
  227.   EachSharedRoom(thisNet, NormalRoomMap, VirtualRoomMap, NULL);
  228.   ITL_Line("");
  229.   return ITL_Send(FINISH);
  230.  
  231.   }
  232. /*
  233. * NormalRoomMap()
  234. *
  235. * This sends the given room's name and cache file name if there is an
  236. * outgoing file pending or one will be built.
  237. */
  238. int NormalRoomMap(SharedRoom *room, int system, int index, int roomslot,
  239. void *d)
  240.   {
  241.   char work[20];
  242.   if (strLen(roomTab[roomslot].rtname) && HasOutgoing(system, index))
  243.     {
  244.     ITL_Line(roomTab[roomslot].rtname);
  245.     sPrintf(work, CACHE_END_NAME, roomslot);
  246.     ITL_Line(work);
  247.  
  248.     }
  249.   return TRUE;
  250.  
  251.   }
  252. /*
  253. * ITL_Line()
  254. *
  255. * Sends the specified line to the SendITLchar function.
  256. */
  257. void ITL_Line(char *data)
  258.   {
  259.   while (*data)
  260.     {
  261.     sendITLchar((int) *data);
  262.     data++;
  263.  
  264.     }
  265.   sendITLchar((int) '\n');
  266.  
  267.   }
  268. /*
  269. * DelFile()
  270. *
  271. * This function kills the named file.
  272. */
  273. void DelFile(DirEntry *f)
  274.   {
  275.   unlink(f->unambig);
  276.  
  277.   }
  278. /*
  279. * MapFileAccepted()
  280. *
  281. * This function is responsible for discovering if the map file is acceptable.
  282. */
  283. char MapFileAccepted()
  284.   {
  285.   FILE *fd;
  286.   char toReturn = TRUE, work[NAMESIZE + 5];
  287.   ToTempArea();
  288.   if (ITL_Receive("moo", FALSE, TRUE, putFLChar, fclose) == ITL_SUCCESS)
  289.     {
  290.     if ((fd = safeopen("moo", READ_ANY)) == NULL)
  291.     toReturn = FALSE;
  292.     else
  293.       {
  294.       GetAString(work, sizeof work, fd);
  295.       if (strLen(work) != 0) toReturn = FALSE;
  296.       fclose(fd);
  297.       unlink("moo");
  298.  
  299.       }
  300.  
  301.     }
  302.   else toReturn = FALSE;
  303.   KillTempArea();
  304.   return toReturn;
  305.  
  306.   }
  307. #define TOP_COMP  4
  308. /*
  309. * netFastTran()
  310. *
  311. * Accept an archive of files?
  312. */
  313. void netFastTran(struct cmd_data *cmds)
  314.   {
  315.   char CheckMap(char *fn, char talk);
  316.   int MTProtocol;
  317.   SYS_FILE fn;
  318.   char work[15];
  319.   MTCompVal  = atoi(cmds->fields[0]);
  320.   MTProtocol = atoi(cmds->fields[1]);
  321.   if (RecMassTransfer || MTCompVal > TOP_COMP || MTCompVal < 0 ||
  322.   !DeCompAvailable(MTCompVal))
  323.     {
  324.     reply(BAD, "nope");
  325.     return;
  326.  
  327.     }
  328.   if (MTProtocol == ZM_PROTOCOL)
  329.     {
  330.     if (!Zmodem || FindProtocolCode(Zmodem, TRUE) == -1)
  331.       {
  332.       reply(BAD, "No protocol");
  333.       return;
  334.  
  335.       }
  336.  
  337.     }
  338.   else if (MTProtocol != DEFAULT_PROTOCOL)
  339.     {
  340.     reply(BAD, "No protocol");
  341.     return;
  342.  
  343.     }
  344.   if (strCmp(cmds->fields[2], "0") != SAMESTRING ||
  345.   strCmp(cmds->fields[3], "-1") != SAMESTRING)
  346.     {
  347.     reply(BAD, " Field 2 & Field 3 no match");
  348.     return;
  349.  
  350.     }
  351.   reply(GOOD, "");
  352.   makeSysName(fn, MAP_FILE, &cfg.netArea);
  353.   if ( logNetResults && netDebug)splitF(netLog, "MAP File:%s\n",fn);
  354.   if (ITL_Receive(fn, FALSE, TRUE, putFLChar, fclose) != ITL_SUCCESS)
  355.     {
  356.     return ;
  357.  
  358.     }
  359.   KillList(&Mappings);
  360.   if (CheckMap(fn, TRUE))
  361.     {
  362.     if( logNetResults )splitF(netLog, "Accepting mass transfer %d\n", MTProtocol);
  363.     if (receive(120) == NAK) return;
  364.  
  365.     sPrintf(work, FAST_RECEIVE, CompExtension(MTCompVal));  /*** bug fix ***/
  366. /*    makeSysName(fn, work, &cfg.netArea); */
  367.     ChangeToCacheDir(&cfg.netArea);           /*** bug fix ***/
  368.  
  369.     if ( logNetResults && netDebug )splitF(netLog, "AMT File(netarea):%s\n",work);
  370.     if (MTProtocol == DEFAULT_PROTOCOL)
  371.       {
  372.       if ( logNetResults && netDebug )splitF(netLog, "Protocol: DEFAULT\n",work);
  373.       if (ITL_Receive(work,FALSE,TRUE, putFLChar, fclose) != ITL_SUCCESS)
  374.         {
  375.         return ;
  376.  
  377.         }
  378.  
  379.       }
  380.     else if (MTProtocol == ZM_PROTOCOL)
  381.       {
  382.       if ( logNetResults && netDebug )splitF(netLog, "Protocol: Zmodem/External\n",work);
  383.       ExternalTransfer(FindProtocolCode(Zmodem, TRUE), work);
  384.       while (MIReady()) inp();
  385.  
  386.       }
  387.     if (access(fn, 0) == 0 )
  388.       {
  389.       reply(GOOD, "");
  390.       /* recovery setup in case of power failure, etc */
  391.       sPrintf(fn, "%s:%d", FAST_RECEIVE, MTCompVal);
  392.       UpdateRecoveryFile(fn);
  393.       RecMassTransfer = TRUE;
  394.       }
  395.     else
  396.       {
  397.       reply(BAD, "No file");
  398.       if( logNetResults )splitF(netLog, "File not received:%s\n",fn);
  399.       makeSysName(fn, MAP_FILE, &cfg.netArea);
  400.       unlink(fn);
  401.  
  402.       }
  403.  
  404.     }
  405.   homeSpace();
  406.   }
  407. /*
  408. * CheckMap()
  409. *
  410. * Checks the map of room names to see if we refuse any.
  411. */
  412. char CheckMap(char *fn, char talk)
  413.   {
  414.   FILE *fd;
  415.   char work[2 * NAMESIZE];
  416.   char toReturn = TRUE, bad;
  417.   FileMap *data;
  418.   RoomSearch arg;
  419.   if (talk && !ITL_Send(STARTUP)) return FALSE;
  420.   if ((fd = safeopen(fn, READ_ANY)) != NULL)
  421.     {
  422.     while (GetAString(work, sizeof work, fd) != NULL)
  423.       {
  424.       bad = TRUE;
  425.       if (strLen(work) == 0) break;
  426.       if (strLen(work) < NAMESIZE)
  427.         {
  428.         strCpy(arg.Room, work);
  429.         if (RoomRoutable(&arg))
  430.           {
  431.           bad = FALSE;
  432.           data = GetDynamic(sizeof *data);
  433.           data->RoomName = strdup(work);
  434.           GetAString(work, sizeof work, fd);
  435.           data->FileName = strdup(work);
  436.           if ( logNetResults && netDebug )splitF(netLog, "MAP Data:RoomName:%s FileName:%s\n"
  437.           ,data->RoomName, data->FileName);
  438.           AddData(&Mappings, data, NULL, FALSE);
  439.  
  440.           }
  441.  
  442.         }
  443.       /* this form lets us respond to several errors with one chunk of code */
  444.       if (bad)
  445.         {
  446.         toReturn = FALSE;
  447.         if (talk) ITL_Line(work);
  448.         GetAString(work, sizeof work, fd);
  449.  
  450.         }
  451.  
  452.       }
  453.     fclose(fd);
  454.  
  455.     }
  456.   else
  457.     {
  458.     printf("Couldn't open %s!\n", fn);
  459.     if (talk) ITL_Line("moo");
  460.     toReturn = FALSE;
  461.  
  462.     }
  463.   if (talk)
  464.     {
  465.     ITL_Line("");
  466.     ITL_Send(FINISH);
  467.  
  468.     }
  469.   return toReturn;
  470.  
  471.   }
  472. /*
  473. * FreeMapping()
  474. *
  475. * Frees a mapping structure.
  476. */
  477. static void FreeMapping(FileMap *data)
  478.   {
  479.   free(data->FileName);
  480.   free(data->RoomName);
  481.   free(data);
  482.  
  483.   }
  484. /*
  485. * KillCacheFiles()
  486. *
  487. * This function kills all cache information concerning a node.  It is called
  488. * when a node is deleted from the nodelist, NOT when caching is simply turned
  489. * off.
  490. */
  491. void KillCacheFiles(int which)
  492.   {
  493.   char ArcFileName[100];
  494.   MakeNetCacheName(ArcFileName, which);
  495.   /* we check this due to the statement after - kill all files! */
  496.   if (ChangeToCacheDir(ArcFileName) == 0)
  497.   wildCard(DelFile, ALL_FILES, FALSE, "", FALSE);
  498.   homeSpace();
  499.   rmdir(ArcFileName);
  500.  
  501.   }
  502. /*
  503. * ReadFastFiles()
  504. *
  505. * This function reads in all of the messages from an Arc file.
  506. */
  507. void ReadFastFiles()
  508.   {
  509.   SYS_FILE fn;
  510.   char work[15];
  511.   void EatMsgFile();
  512.   if (!RecMassTransfer) return;
  513.   RecMassTransfer = FALSE;
  514.   sprintf(work, FAST_RECEIVE, CompExtension(MTCompVal));
  515.   makeSysName(fn, work, &cfg.netArea);
  516.   if ( logNetResults && netDebug)splitF(netLog, "RFF:%s(netarea)\n",fn);
  517.   NetDeCompress(MTCompVal, fn);
  518.   RunList(&Mappings, EatMsgFile);
  519.   KillNetDeCompress();
  520.   if (!cfg.BoolFlags.debug) unlink(fn);
  521.   makeSysName(fn, MAP_FILE, &cfg.netArea);
  522.   if (!cfg.BoolFlags.debug) unlink(fn);
  523.   KillList(&Mappings);
  524.   homeSpace();
  525.   }
  526. /*
  527. * EatMsgFile()
  528. *
  529. * This eats a message file extracted from an archive file.
  530. */
  531. void EatMsgFile(FileMap *data)
  532.   {
  533.   char fn[80];
  534.   char vfn[70];
  535.   int VirtNo;
  536.   RoomSearch arg;
  537.   extern char *SharingRefusal[];
  538.   strCpy(arg.Room, data->RoomName);
  539.   if (!RoomRoutable(&arg))
  540.     {
  541.     if( logNetResults )splitF(netLog, "Ooops - can't find %s\n", data->RoomName);
  542.     return;
  543.  
  544.     }
  545.   if (arg.virtual)
  546.     {
  547.     SetUpForVirtuals(arg.index, &VirtNo, vfn);
  548.     MakeDeCompressedFilename(fn, data->FileName);
  549.     VirtualCopyFileToFile(fn, vfn);
  550.  
  551.     }
  552.   else
  553.     {
  554.     MakeDeCompressedFilename(fn, data->FileName);
  555.     ReadNetRoomFile(arg.index, fn);
  556.  
  557.     }
  558.  
  559.   }
  560. /*
  561. * CacheMessages()
  562. *
  563. * This function is tasked with building cache files as needed.  We loop
  564. * through all the systems in the system list.  Those for which the
  565. * MassTransfer flag is active will cause the system to see if there are
  566. * any messages in the message base that are not in the cache for that
  567. * system.  If any are found, the messages are added to their respective
  568. * files (or create as necessary) and then the compression program is run for
  569. * that particular cache.  Flags must be set appropriately, of course.
  570. */
  571. char CacheUpdated;
  572. void CacheMessages(MULTI_NET_DATA whichNets, char VirtOnly)
  573.   {
  574.   int rover;
  575.   for (rover = 0; rover < cfg.netSize; rover++)
  576.     {
  577.     if ((netTab[rover].ntMemberNets & whichNets))
  578.     CacheSystem(rover, VirtOnly);
  579.  
  580.     }
  581.  
  582.   }
  583. /*
  584. * CacheSystem()
  585. *
  586. * This function caches a single system.  It is separated from CacheMessages()
  587. * so we can cache systems on an individual basis.
  588. */
  589. void CacheSystem(int system, char VirtOnly)
  590.   {
  591.   int CacheRoom(SharedRoom *room, int system, int index, int roomslot, void *d);
  592.   extern void (*NetPrintTarget)(char *format, ...);
  593.   char ArcFileName[60], Files[60], BaseName[40];
  594.   if (!netTab[system].ntflags.MassTransfer) return;
  595.   if (!gotCarrier()) DisableModem(TRUE);
  596.   CacheUpdated = FALSE;
  597.   NetPrintTarget = ToFile;
  598.   EachSharedRoom(system, (VirtOnly) ? NULL : CacheRoom,
  599.   CacheVirtualRoom, NULL);
  600.   if (CacheUpdated)
  601.     {
  602.     putNet(system, &netBuf);
  603.     if (CompAvailable(GetCompression(system)))
  604.       {
  605.       sPrintf(BaseName, NETMSGS, CompExtension(GetCompression(thisNet)));
  606.       NetCacheName(ArcFileName, system, BaseName);
  607.       if ( logNetResults && netDebug )splitF(netLog, "ArcFileName:%s\n",ArcFileName);
  608.       NetCacheName(Files, system, CACHED_FILES);
  609.       if ( logNetResults && netDebug )splitF(netLog, "Files:%s\n",Files);
  610.       Compress(GetCompression(system), Files, ArcFileName);
  611.       if (access(ArcFileName, 0) != 0)
  612.         {
  613.         sPrintf(msgBuf.mbtext, "Compress failed for %s?", netBuf.netName);
  614.         if( logNetResults )splitF(netLog, "ERROR: %s\n", msgBuf.mbtext);
  615.         aideMessage("Net Aide", FALSE);
  616.  
  617.         }
  618.  
  619.       }
  620.     UpdVirtStuff();
  621.  
  622.     }
  623.   if (!gotCarrier()) EnableModem(TRUE);
  624.   NetPrintTarget = mTrPrintf;
  625.  
  626.   }
  627. /*
  628. * CacheRoom()
  629. *
  630. * This caches a room's messages as necessary.
  631. */
  632. int CacheRoom(SharedRoom *room, int system, int index, int roomslot,
  633. void *d)
  634.   {
  635.   extern char PrTransmit;
  636.   char oldNet;
  637.   int MsgCount;
  638.   extern NetInfo NetStyle;
  639.   char work[10], tempNm[3*NAMESIZE], commnd, doit, *name;
  640.   if (roomTab[roomslot].rtlastMessage > room->lastMess &&
  641.   strLen(roomTab[roomslot].rtname))
  642.     {
  643.     if (thisNet != system)
  644.     getNet(system, &netBuf);
  645.     Addressing(system, index, &commnd, &NetStyle.addr1, &NetStyle.addr2,
  646.     &NetStyle.addr3, &name, &doit);
  647.     NetStyle.sendfunc = putFLChar;
  648.     PrTransmit = FALSE;
  649.     sPrintf(work, CACHE_END_NAME, roomslot);
  650.     NetCacheName(tempNm, system, work);
  651.     if ((upfd = safeopen(tempNm, APPEND_ANY)) != NULL)
  652.       {
  653.       oldNet = inNet;
  654.       inNet = NET_CACHE;
  655.       MsgCount = showMessages(NEWoNLY, FALSE,
  656.       room->lastMess, NetRoute);
  657.       inNet = oldNet;
  658.       fclose(upfd);
  659.       SetHighValues(index);
  660.       if (MsgCount == 0 && !GetFA(room->mode))
  661.       unlink(tempNm);
  662.       else if (MsgCount != 0)
  663.         {
  664.         SetFA(netBuf.netRooms[index].mode);
  665.         CacheUpdated = TRUE;
  666.  
  667.         }
  668.  
  669.       }
  670.     PrTransmit = TRUE;
  671.  
  672.     }
  673.   return TRUE;
  674.  
  675.   }
  676. /*
  677. * RecoverMassTransfer()
  678. *
  679. * This function is charged with recovering a mass transfer file that was
  680. * not processed in the last net session due to a crash of some sort.
  681. */
  682. void RecoverMassTransfer(char *line)
  683.   {
  684.   SYS_FILE fn;
  685.   char *colon;
  686.   makeSysName(fn, MAP_FILE, &cfg.netArea);
  687.   RecMassTransfer = TRUE;
  688.   if ( logNetResults && netDebug)splitF(netLog, "Recover from:%s\n",fn);
  689.   CheckMap(fn, FALSE);
  690.   if ((colon = strchr(line, ':')) == NULL) return;
  691.   MTCompVal = atoi(colon + 1);
  692.   ReadFastFiles();
  693.  
  694.   }
  695. /*
  696. * UnCacheRoom()
  697. *
  698. * This turns off the cached flag for a given room shared thing.
  699. */
  700. int UnCacheRoom(SharedRoom *room, int system, int index, int roomslot,
  701. void *d)
  702.   {
  703.   if (strLen(roomTab[roomslot].rtname))
  704.     {
  705.     UnSetFA(netBuf.netRooms[index].mode);
  706.     /* this is valid only so long as we uncache on-line, so in case ... */
  707.     if (inNet != NON_NET) SR_Sent[index] = 1;
  708.  
  709.     }
  710.   return TRUE;
  711.  
  712.   }
  713.